import { readFileSync } from "fs";
import VersionManager from "./libs/versionManager";

interface ICmd {
    // 简写命令
    alias: string[];
    // 解释
    desc: string;
    // 执行函数
    action: Function;
    /** 参数 */
    args?: string[];
    /** 是否默认命令 */
    default?: boolean;
}

let commands: { [key: string]: ICmd } = {
    "--help": {
        alias: ['-h'],
        desc: "显示帮助信息",
        action: showHelp,
    },
    "--gen-all-diff": {
        alias: ['-ga'],
        desc: "指定版本对资源目录下的所有版本进行比对，生成所有的差量更新包",
        action: genAllDiff,
    },
    "--gen-ab": {
        alias: ["-g", "-z"],
        desc: "生成指定A，B版本之间的差异包",
        action: genVersionByAB,
    },

    "--unzip": {
        alias: ["-u"],
        desc: "解压指定版本号资源包",
        action: unZipVersion,
    },

    "--publish": {
        alias: ["-p"],
        desc: "发布版本，拷贝指定版本的manifest,version文件到packges目录",
        action: publishVersion,
    },

    "--publish-w": {
        alias: ["-pw"],
        desc: "发布白名单测试资源,拷贝manifest,private-version文件到packages目录",
        action: publishVersionWhite,
    },
    "--jenkiens-gen-all-diff": {
        alias: ['-jga'],
        desc: "指定Jenkins版本对应的差量包生成",
        action: genAllDiffByJenkiens,
    },
    "--jenkiens-publish": {
        alias: ['-jp'],
        desc: "发布指定Jenkins版本",
        action: publishVersionByJenkiens,
    },

    "--jenkiens-publish-w": {
        alias: ['-jpw'],
        desc: "发布指定Jenkins版本",
        action: publishVersionWhiteByJenkiens,
    },


    "--test": {
        alias: ['-t'],
        desc: "测试命令及参数接口",
        action: testAction,
    }
}


let keys: string[] = []; //cache of command's key ("--help"...)
var alias_map: { [name: string]: string } = {}; // mapping of alias_name -> name
var parsed_cmds: ICmd[] = []; //cmds of parsed out.

/**
 * initialize
 */

function initialize() {
    keys = Object.keys(commands);
    for (var key in commands) {
        var alias_array = commands[key]["alias"];
        alias_array.forEach(function (element, index, array) {
            alias_map[element] = key;
        });
    };

    parsed_cmds = parseCommandLine(process.argv);
    parsed_cmds.forEach(function (element, index, array) {
        exec(element);
    });
}

initialize();

/**
 * parse command line args
 */
function parseCommandLine(args: string[]) {
    var parsed_cmds: ICmd[] = [];

    if (args.length <= 2) {
        parsed_cmds.push(defaultCommand());
    } else {

        var cli = args.slice(2);

        var pos = 0;
        var cmd: ICmd;

        cli.forEach(function (element, index, array) {

            //replace alias name with real name.
            if (element.indexOf('--') === -1 && element.indexOf('-') === 0) {
                cli[index] = alias_map[element];
            }

            //parse command and args
            if (cli[index].indexOf('--') === -1) {
                cmd?.args?.push(cli[index]);
            } else {

                if (keys.indexOf(cli[index]) == -1) {
                    throw new Error("not support command:" + cli[index]);
                };

                pos = index;
                cmd = commands[cli[index]];
                if (typeof cmd.args == 'undefined') {
                    cmd.args = [];
                };
                parsed_cmds.push(cmd);
            }
        });
    };

    return parsed_cmds;
};

/**
 * default command when no command line argas provided.
 */
function defaultCommand() {
    if (keys.length <= 0) {
        throw new Error("Error: there is no command at all!");
    };

    for (var p in commands) {
        if (commands[p].default) {
            return commands[p];
        };
    };

    if (keys.indexOf("--help") != -1) {
        return commands["--help"];
    } else {
        return commands[keys[0]];
    };
};

/**
 * execute a command
 */
function exec(cmd: ICmd) {
    if (typeof cmd.action === "function") {
        cmd.action(...cmd.args as any);
    };
};


/** 显示帮助 */
function showHelp() {
    var usage = "usage: \n";
    for (var p in commands) {
        if (typeof commands[p] !== "function") {
            usage += "\t " + p + "\t " + commands[p].alias + "\t " + commands[p].desc + "\n ";
        };
    };
    console.log(usage);
}

/** 生成指定版本对所有其他版本的差异 */
function genAllDiff(version: string) {
    if (!version) return;
    console.log(version);
    VersionManager.genAllVersions(version);
}

/** 生成2个指定版本之间的资源差异 */
function genVersionByAB(versionA: string, versionB: string) {
    if (!versionA || !versionB) {
        throw new Error("参数错误，需要输入2个存在的版本号");
    }
    VersionManager.genDiffVersion(versionA, versionB);
}

/** 解压指定资源包 */
function unZipVersion(version: string) {
    VersionManager.unzipVersion(version);
}

/** 发布版本 */
function publishVersion(version: string) {
    VersionManager.publish(version);
}

function publishVersionWhite(version: string) {
    VersionManager.publishWhite(version);
}

/** 根据Jenkins版本号，获取实际构建版本号 */
function jenkiens2version(jenkiens: string) {
    const __CONFIG__ = require("./config.json");
    const versionFile = `${__CONFIG__.assetsPath}/${jenkiens}.txt`;
    const version = readFileSync(versionFile, "utf-8");
    return version;
}

/** 根据Jenkins版本号，生成热更新包 */
function genAllDiffByJenkiens(jenkiens: string) {
    VersionManager.genAllVersions(jenkiens2version(jenkiens));
}

/** 根据Jenkins版本号，发布白名单 */
function publishVersionWhiteByJenkiens(jenkiens: string) {
    VersionManager.publishWhite(jenkiens2version(jenkiens));
}

/** 根据Jenkins版本号，发布正式版本 */
function publishVersionByJenkiens(jenkiens: string) {
    VersionManager.publish(jenkiens2version(jenkiens));
}




/** 测试命令及接口 */
function testAction(...args: string[]) {
    console.log("测试接口, 参数为：", ...args);
}